/**
 * @author Ahammer
 * @date   2010 04
 * @update 
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package opgui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSpinner;
import javax.swing.JToolBar;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.InternationalFormatter;
import main.IqmTools;
import main.Tank;

public class IqmFracHiguchiGUI extends IqmOperatorJFrame implements IqmOperatorGUIBuilder,
															   ActionListener, ChangeListener {

	private  ParameterBlockJAI     pbJAI       = null;  //  @jve:decl-index=0:
	//public  ImgProcFuncJFrame    opGUIFrame  = null;
	//private  IqmFracHiguchiGUI   opGUIFrame  = null;  //actionPerformed events werden in dieser Klasse abgehandelt
  
	private int width;
	private int height;
	
	private int numMaxK = 0;
	private int numK    = 0;
 	 
	private JPanel 				  jPanelNumK    = null;	
	private JLabel				  jLabelNumK	= null;
	private JSpinner			  jSpinnerNumK  = null;
	
	private JRadioButtonMenuItem  buttProj       = null;
	private JRadioButtonMenuItem  buttSep        = null;
	private JRadioButtonMenuItem  buttMeand      = null;
	private JRadioButtonMenuItem  buttCont       = null;
	private JRadioButtonMenuItem  buttHiddenAppend = null;
	private JToolBar              jToolBarAppend   = null;
	private ButtonGroup           buttGroupAppend  = null;
	
	private JRadioButtonMenuItem  buttIncl       = null;
	private JRadioButtonMenuItem  buttExcl       = null;
	private JRadioButtonMenuItem  buttHiddenBack = null;
	private JToolBar              jToolBarBack   = null;
	private ButtonGroup           buttGroupBack  = null;
	
	private  JCheckBox 	    jCheckBoxDx	   = null;
	private  JCheckBox 	    jCheckBoxDy	   = null;
	
	private JPanel 		jPanelRegression	= null;	
	private JLabel		jLabelRegression  	= null;;
	private JPanel 		jPanelRegStart   	= null;	
	private JLabel		jLabelRegStart	 	= null;
	private JSpinner	jSpinnerRegStart 	= null;	
	private JPanel 		jPanelRegEnd    	= null;	
	private JLabel		jLabelRegEnd		= null;
	private JSpinner	jSpinnerRegEnd  	= null;
	
	private  JCheckBox	jCheckBoxShowPlot			= null;
	private  JCheckBox	jCheckBoxDeleteExistingPlot = null;
	
	
	
	/**
	 * This method sets the current parameter block to the argument
	 * @param ParameterBlockJAI pb
	 *
	 */
	@Override
	public void setParameterBlock(ParameterBlockJAI arg){
		pbJAI = arg;
		IqmTools.setCurrParameterBlockJAI(pbJAI);	
	}
	/**
	 * This method sets the current parameter block
	 * The individual values of the GUI  current ParameterBlock
	 *
	 */
	@Override
	public void setParameterBlock(){
		
		pbJAI.setParameter("NumK",  ((Number)jSpinnerNumK.getValue()).intValue());
		
		if (buttProj.isSelected()) pbJAI.setParameter("Append", 0);
		if (buttSep.isSelected())  pbJAI.setParameter("Append", 1);
		if (buttMeand.isSelected())pbJAI.setParameter("Append", 2);
		if (buttCont.isSelected()) pbJAI.setParameter("Append", 3);
		
		if (buttIncl.isSelected()) pbJAI.setParameter("Back", 0);
		if (buttExcl.isSelected()) pbJAI.setParameter("Back", 1);
		
		if (jCheckBoxDx.isSelected())  pbJAI.setParameter("Dx", 1);
		if (!jCheckBoxDx.isSelected()) pbJAI.setParameter("Dx", 0);
		if (jCheckBoxDy.isSelected())  pbJAI.setParameter("Dy", 1);
		if (!jCheckBoxDy.isSelected()) pbJAI.setParameter("Dy", 0);

		pbJAI.setParameter("RegStart", ((Number)jSpinnerRegStart.getValue()).intValue());
		pbJAI.setParameter("RegEnd",   ((Number)jSpinnerRegEnd.getValue()).intValue());
		
		if (jCheckBoxShowPlot.isSelected())  			pbJAI.setParameter("ShowPlot", 1);
		if (!jCheckBoxShowPlot.isSelected()) 			pbJAI.setParameter("ShowPlot", 0);
		if (jCheckBoxDeleteExistingPlot.isSelected()) 	pbJAI.setParameter("DeleteExistingPlot", 1);
		if (!jCheckBoxDeleteExistingPlot.isSelected())	pbJAI.setParameter("DeleteExistingPlot", 0);

		IqmTools.setCurrParameterBlockJAI(pbJAI);	
	}
	
	/**
	 * This method sets the current parameter values
	 *
	 */
	@Override
	public void setParameterValues(){
		int idx = IqmTools.getCurrManagerImgIndex();
	    PlanarImage pi = Tank.getCurrentTankImageAt(idx); 
	       if (pi == null){
	    	   System.out.println("IqmFracHiguchiGUI: Current image not defined");
	    	   return;
	       }
//	    int pixelSize = pi.getColorModel().getPixelSize();
//      int numBands  = pi.getNumBands(); 
//      String type = IqmTools.getCurrImgTyp(pixelSize, numBands);
//      String type = IqmTools.getCurrImgTyp(pi);

		buttHiddenAppend.setSelected(true);
		
		
	    jSpinnerNumK.removeChangeListener(this);	
	    jSpinnerNumK.setValue(pbJAI.getIntParameter("NumK"));
	    jSpinnerNumK.addChangeListener(this);
	    	    

		if (pbJAI.getIntParameter("Append") == 0) buttProj.setSelected(true);
		if (pbJAI.getIntParameter("Append") == 1) buttSep.setSelected(true);
		if (pbJAI.getIntParameter("Append") == 2) buttMeand.setSelected(true);
		if (pbJAI.getIntParameter("Append") == 3) buttCont.setSelected(true);

		if (pbJAI.getIntParameter("Back") == 0) buttIncl.setSelected(true);
		if (pbJAI.getIntParameter("Back") == 1) buttExcl.setSelected(true);
		
	    if (pbJAI.getIntParameter("Dx") == 0)   jCheckBoxDx.setSelected(false);
	    if (pbJAI.getIntParameter("Dx") == 1)   jCheckBoxDx.setSelected(true);
	    if (pbJAI.getIntParameter("Dy") == 0)   jCheckBoxDy.setSelected(false);
	    if (pbJAI.getIntParameter("Dy") == 1)   jCheckBoxDy.setSelected(true);
		
	    jSpinnerRegStart.removeChangeListener(this);	
	    jSpinnerRegStart.setValue(pbJAI.getIntParameter("RegStart"));
	    jSpinnerRegStart.addChangeListener(this);
	    
	    jSpinnerRegEnd.removeChangeListener(this);	
	    jSpinnerRegEnd.setValue(pbJAI.getIntParameter("RegEnd"));
	    jSpinnerRegEnd.addChangeListener(this);
	    
	    if (pbJAI.getIntParameter("ShowPlot") == 0)   jCheckBoxShowPlot.setSelected(false);
	    if (pbJAI.getIntParameter("ShowPlot") == 1)   jCheckBoxShowPlot.setSelected(true);
	    if (pbJAI.getIntParameter("DeleteExistingPlot") == 0)   jCheckBoxDeleteExistingPlot.setSelected(false);
	    if (pbJAI.getIntParameter("DeleteExistingPlot") == 1)   jCheckBoxDeleteExistingPlot.setSelected(true);

	}
	/**
	 * constructor
	 */
	public IqmFracHiguchiGUI() {

	}
	/**
	 * This method creates and shows the GUI
	 * 
	 */
	@Override
	public void createIqmOperatorGUI() {
		//opGUIFrame = new ImgProcFuncJFrame();  //actionPerforemd events werden in dieser Klasse abgehandelt
		//opGUIFrame = new IqmFracHiguchiGUI();      //actionPerforemd events werden in dieser Klasse abgehandelt
		//this.getJContentPane();
		this.initialize(); //Aufruf von ImgProcFuncJFrame
		this.setTitle("FracHiguchi"); 
	
		PlanarImage pi = Tank.getCurrentTankImageAt(IqmTools.getCurrManagerImgIndex());
		width  = pi.getWidth();
		height = pi.getHeight();
	
		//Dimension dim = this.getSize();
		//this.setSize(dim.width, dim.height+150);
		this.getJContentPane().add(getJPanelNumK(),       getGridBagConstraintsNumK());
		this.getJContentPane().add(getJToolBarAppend(),   getGridBagConstraintsAppend());
		this.getJContentPane().add(getJToolBarBack(),     getGridBagConstraintsBack());
		this.getJContentPane().add(getJCheckBoxDx(),      getGridBagConstraintsDx());
		this.getJContentPane().add(getJCheckBoxDy(),      getGridBagConstraintsDy());	
		this.getJContentPane().add(getJPanelRegression(), getGridBagConstraintsRegression());
		this.getJContentPane().add(getJCheckBoxShowPlot(),				getGridBagConstraintsShowPlot());
		this.getJContentPane().add(getJCheckBoxDeleteExistingPlot(),    getGridBagConstraintsDeleteExistingPlot());	
		
		//this.repaint();
		if (pbJAI == null) pbJAI = new ParameterBlockJAI("IqmFracHiguchi");  //nur wenn das erste mal aufgerufen
		//pbJAI = new ParameterBlockJAI("IqmFracHiguchi"); //immer der default Block
		IqmTools.setCurrParameterBlockJAI(pbJAI);	
		setParameterValues();
		
		//Set image dependent initial values;
		numMaxK = this.getMaxHiguchiNumber(width,  height);
		//numK = numMaxK;
		numK = numMaxK/4*3;
		setJSpinnerNumKandRegEnd(numK, numMaxK);
	
	    setParameterBlock();
		this.pack();
	}

	/**
	 * This method gets the maximal k
	 * 
	 */
	private int getMaxHiguchiNumber(int width, int height) {
	
		int kMax = 1; //inclusive original image
	    if (buttProj.isSelected() || buttSep.isSelected()){
	    	if (width <= height){
	    		kMax = width/3; 
	    	}else{
	    		kMax = height/3;
	    	}
		}
	    if (buttCont.isSelected() || buttMeand.isSelected()){	   
	    	kMax = (width * height)/3;	    	
		}
		return kMax;
	}
	/**
	 * This method sets the jSpinner for k
	 * @param numMaxK
	 * 
	 */
	private void setJSpinnerNumKandRegEnd(int numK, int numMaxK){
		//System.out.println("IqmFracHiguchiGUI: numberMax: " + numberMax);
		SpinnerModel sModel = new SpinnerNumberModel(numK, 3, numMaxK, 1); //init, min, max, step
		jSpinnerNumK.removeChangeListener(this);
		jSpinnerNumK.setModel(sModel);
	    jSpinnerNumK.setValue(numK);
	    jSpinnerRegEnd.removeChangeListener(this);	
	    //jSpinnerRegEnd.setValue(numK);
		SpinnerModel sModelRegEnd = new SpinnerNumberModel(numK, 3, numMaxK, 1); //init, min, max, step
		jSpinnerRegEnd.setModel(sModelRegEnd);
	    jSpinnerRegEnd.addChangeListener(this);
		JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerNumK.getEditor()  ;
		JFormattedTextField ftf = defEditor.getTextField() ;
		ftf.setEditable(false);
		InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
		DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
		decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;	
	    jSpinnerNumK.addChangeListener(this);
	}
	private  GridBagConstraints getGridBagConstraintsNumK(){
		GridBagConstraints gridBagConstraintsNumK = new GridBagConstraints();
		gridBagConstraintsNumK.gridx = 1;
		gridBagConstraintsNumK.gridy = 5;
		gridBagConstraintsNumK.gridwidth = 2;//?
		gridBagConstraintsNumK.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsNumK.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsNumK;
	}
	private  GridBagConstraints getGridBagConstraintsAppend(){
		GridBagConstraints gridBagConstraintsAppend = new GridBagConstraints();
		gridBagConstraintsAppend.gridx = 1;
		gridBagConstraintsAppend.gridy = 6;
		gridBagConstraintsAppend.gridwidth = 3;//?
		gridBagConstraintsAppend.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsAppend.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsAppend;
	}
	private  GridBagConstraints getGridBagConstraintsBack(){
		GridBagConstraints gridBagConstraintsBack = new GridBagConstraints();
		gridBagConstraintsBack.gridx = 1;
		gridBagConstraintsBack.gridy = 7;
		gridBagConstraintsBack.gridwidth = 2;//?
		gridBagConstraintsBack.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsBack.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsBack;
	}
	private  GridBagConstraints getGridBagConstraintsDx(){
		GridBagConstraints gridBagConstraintsDx = new GridBagConstraints();
		gridBagConstraintsDx.gridx = 1;
		gridBagConstraintsDx.gridy = 8;
		gridBagConstraintsDx.anchor = GridBagConstraints.LINE_START;
		gridBagConstraintsDx.insets = new Insets(10,20,0,0); //top left bottom right
		//gridBagConstraintsDx.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsDx;
	}
	private  GridBagConstraints getGridBagConstraintsDy(){
		GridBagConstraints gridBagConstraintsDy = new GridBagConstraints();
		gridBagConstraintsDy.gridx = 2;
		gridBagConstraintsDy.gridy = 8;
		gridBagConstraintsDy.anchor = GridBagConstraints.LINE_START;
		gridBagConstraintsDy.insets = new Insets(10,0,0,0); //top left bottom right
		//gridBagConstraintsDy.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsDy;
	}
	private  GridBagConstraints getGridBagConstraintsRegression(){
		GridBagConstraints gridBagConstraintsRegression = new GridBagConstraints();
		gridBagConstraintsRegression.gridx = 1;
		gridBagConstraintsRegression.gridy = 9;
		gridBagConstraintsRegression.gridwidth = 3;//?
		gridBagConstraintsRegression.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsRegression.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsRegression;
	}
	private  GridBagConstraints getGridBagConstraintsShowPlot(){
		GridBagConstraints gridBagConstraintsShowPlot = new GridBagConstraints();
		gridBagConstraintsShowPlot.gridx = 1;
		gridBagConstraintsShowPlot.gridy = 10;
		gridBagConstraintsShowPlot.anchor = GridBagConstraints.LINE_START;
		gridBagConstraintsShowPlot.insets = new Insets(10,20,10,0); //top left bottom right
		//gridBagConstraintsShowPlot.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsShowPlot;
	}
	private  GridBagConstraints getGridBagConstraintsDeleteExistingPlot(){
		GridBagConstraints gridBagConstraintsDeleteExistingPlot = new GridBagConstraints();
		gridBagConstraintsDeleteExistingPlot.gridx = 2;
		gridBagConstraintsDeleteExistingPlot.gridy = 10;
		gridBagConstraintsDeleteExistingPlot.anchor = GridBagConstraints.LINE_START;
		gridBagConstraintsDeleteExistingPlot.insets = new Insets(10,0,10,0); //top left bottom right
		//gridBagConstraintsDeleteExistingPlot.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsDeleteExistingPlot;
	}

	//------------------------------------------------------------------------------------------------------

	/**
	 * This method updates the GUI if needed
	 * This method overrides IqmOperatorJFrame
	 */
	public void updateIqmOperatorGUI(){
		numMaxK = this.getMaxHiguchiNumber(width, height);
		if (numK > numMaxK) numK = numMaxK;	
		this.setJSpinnerNumKandRegEnd(numK, numMaxK);
	}
	//----------------------------------------------------------------------------------------------------------
	/**
	 * This method initializes jJPanelNumK	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelNumK() {
		if (jPanelNumK == null) {
			jPanelNumK = new JPanel();
			jPanelNumK.setLayout(new BorderLayout());		
			jLabelNumK = new JLabel("Number of dada series (delay) k: ");
			//jLabelNumK.setPreferredSize(new Dimension(70, 22));
			jLabelNumK.setHorizontalAlignment(JLabel.RIGHT);
			SpinnerModel sModel = new SpinnerNumberModel(3, 3, Integer.MAX_VALUE, 1); //init, min, max, step
			jSpinnerNumK = new JSpinner(sModel);
			//jSpinnerNumK = new JSpinner();
			jSpinnerNumK.setPreferredSize(new Dimension(40, 22));
			jSpinnerNumK.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerNumK.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			ftf.setEditable(false);
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelNumK.add(jLabelNumK,   BorderLayout.NORTH);
			jPanelNumK.add(jSpinnerNumK, BorderLayout.CENTER);			
		}
		return jPanelNumK;
	}
	//-------------------------------------------------------------------------------------------
	/**
	 * This method initializes the Option
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtProj() {
		//if (buttProj == null) {
			buttProj  = new JRadioButtonMenuItem();
			buttProj .setText("Rows and Columns projected (fast)");
			buttProj .setToolTipText("rows and columns are projected to a single data series respectively");
			buttProj .addActionListener(this);
			buttProj.setActionCommand("parameter");
		//}
		return buttProj;
	}
	/**
	 * This method initializes the Option:
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtSep() {
		//if (buttSep == null) {
			buttSep  = new JRadioButtonMenuItem();
			buttSep .setText("Rows and columns separately and averaged (slow)");
			buttSep .setToolTipText("every row and column is separately calculated");
			buttSep .addActionListener(this);
			buttSep.setActionCommand("parameter");
		//}
		return buttSep;
	}
	/**
	 * This method initializes the Option:
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMeand() {
		//if (buttMeand == null) {
			buttMeand  = new JRadioButtonMenuItem();
			buttMeand .setText("Single meander row (very slow)");
			buttMeand .setToolTipText("rows are meander like stitched together to a single data series");
			buttMeand .addActionListener(this);
			buttMeand.setActionCommand("parameter");
		//}
		return buttMeand;
	}
	/**
	 * This method initializes the Option:	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtCont() {
		//if (buttCont == null) {
			buttCont  = new JRadioButtonMenuItem();
			buttCont .setText("Single contiguous row (very slow)");
			buttCont .setToolTipText("rows are contiguously stitched together to a single data series");
			buttCont .addActionListener(this);
			buttCont.setActionCommand("parameter");
		//}
		return buttCont;
	}
	
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtHiddenAppend() {
		//if (buttHiddenAppend == null) {
			buttHiddenAppend  = new JRadioButtonMenuItem();
			buttHiddenAppend .setText("Hidden");
			buttHiddenAppend.setVisible(false);
		//}
		return buttHiddenAppend;
	}


	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarAppend() {
//		if (jToolBarAppend== null) {
			jToolBarAppend = new JToolBar("Options");
			jToolBarAppend.setOrientation(1); // 0 Horizontal 1 Vertical orientation
			jToolBarAppend.add(getJRadioButtonMenuButtProj());
			jToolBarAppend.add(getJRadioButtonMenuButtSep());
			jToolBarAppend.add(getJRadioButtonMenuButtMeand());
			jToolBarAppend.add(getJRadioButtonMenuButtCont());
			jToolBarAppend.add(getJRadioButtonMenuButtHiddenAppend());
			//jToolBarAppend.addSeparator();
			this.setButtonGroupAppend();	//Gruppieren der JRadioButtons
//		}
		return jToolBarAppend;
	}

	private  void setButtonGroupAppend() {
		//if (ButtonGroup buttGroup == null) {
			buttGroupAppend = new ButtonGroup();
			buttGroupAppend.add(buttProj);
			buttGroupAppend.add(buttSep);
			buttGroupAppend.add(buttMeand);
			buttGroupAppend.add(buttCont);
			buttGroupAppend.add(buttHiddenAppend);
	}
	//-----------------------------------------------------------------------------------------
	/**
	 * This method initializes the Option
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtIncl() {
		//if (buttIncl == null) {
			buttIncl  = new JRadioButtonMenuItem();
			buttIncl .setText("Inclusive Background");
			buttIncl .setToolTipText("calculation is carried out including zero values");
			buttIncl .addActionListener(this);
			buttIncl.setActionCommand("parameter");
		//}
		return buttIncl;
	}
	/**
	 * This method initializes the Option:
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtExcl() {
		//if (buttExcl == null) {
			buttExcl  = new JRadioButtonMenuItem();
			buttExcl .setText("Exclusive Background");
			buttExcl .setToolTipText("calculation is carried out excluding zero values");
			buttExcl .addActionListener(this);
			buttExcl.setActionCommand("parameter");
			//buttExcl.setEnabled(false);
		//}
		return buttExcl;
	}
	
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtHiddenBack() {
		//if (buttHiddenBack == null) {
			buttHiddenBack  = new JRadioButtonMenuItem();
			buttHiddenBack .setText("Hidden");
			buttHiddenBack.setVisible(false);
		//}
		return buttHiddenBack;
	}

	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarBack() {
//		if (jToolBarBack== null) {
			jToolBarBack = new JToolBar("Options");
			jToolBarBack.setOrientation(1); // 0 Horizontal 1 Vertical orientation
			jToolBarBack.add(getJRadioButtonMenuButtIncl());
			jToolBarBack.add(getJRadioButtonMenuButtExcl());
			jToolBarBack.add(getJRadioButtonMenuButtHiddenBack());
			//jToolBarBack.addSeparator();
			this.setButtonGroupBack();	//Gruppieren der JRadioButtons
//		}
		return jToolBarBack;
	}

	private  void setButtonGroupBack() {
		//if (ButtonGroup buttGroup == null) {
			buttGroupBack = new ButtonGroup();
			buttGroupBack.add(buttIncl);
			buttGroupBack.add(buttExcl);
			buttGroupBack.add(buttHiddenBack);
	}
	//------------------------------------------------------------------------------------	
	/**
	 * This method initializes jCheckBoxDx	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private  JCheckBox getJCheckBoxDx() {
		if (jCheckBoxDx == null) {
			jCheckBoxDx = new JCheckBox();
			jCheckBoxDx.setText("Dx");
			jCheckBoxDx.addActionListener(this);			
			jCheckBoxDx.setActionCommand("parameter");			
		}
		return jCheckBoxDx;
	}
	//------------------------------------------------------------------------------------
	/**
	 * This method initializes jCheckBoxDy	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private  JCheckBox getJCheckBoxDy() {
		if (jCheckBoxDy == null) {
			jCheckBoxDy = new JCheckBox();
			jCheckBoxDy.setText("Dy");
			jCheckBoxDy.addActionListener(this);			
			jCheckBoxDy.setActionCommand("parameter");			
		}
		return jCheckBoxDy;
	}
	//-----------------------------------------------------------------------------------------
	/**
	 * This method initializes jJPanelRegression	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelRegression() {
		if (jPanelRegression== null) {
			jPanelRegression = new JPanel();
			jPanelRegression.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));				
			jPanelRegression.add(getJLabelRegression());
			jPanelRegression.add(getJPanelRegStart());
			jPanelRegression.add(getJPanelRegEnd());			
		}
		return jPanelRegression;
	}
	//------------------------------------------------------------------------------------------
	/**
	 * This method initializes jLabelRegression	
	 * 	
	 * @return javax.swing.JLabel
	 */
	private JLabel getJLabelRegression() {
		if (jLabelRegression == null){
			jLabelRegression = new JLabel("Regression:");
		}
		return jLabelRegression;	
	}
	//----------------------------------------------------------------------------------------------------------
	/**
	 * This method initializes jJPanelRegStart	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelRegStart() {
		if (jPanelRegStart == null) {
			jPanelRegStart = new JPanel();
			jPanelRegStart.setLayout(new FlowLayout());		
			jLabelRegStart = new JLabel("Start:");
			//jLabelRegStart.setPreferredSize(new Dimension(40, 22));
			jLabelRegStart.setHorizontalAlignment(JLabel.RIGHT);
			SpinnerModel sModel = new SpinnerNumberModel(1, 1, 2, 1); //init, min, max, step
			jSpinnerRegStart = new JSpinner(sModel);
			//jSpinnerRegStart = new JSpinner();
			jSpinnerRegStart.setPreferredSize(new Dimension(60, 22));
			jSpinnerRegStart.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerRegStart.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			ftf.setEditable(false);
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelRegStart.add(jLabelRegStart);
			jPanelRegStart.add(jSpinnerRegStart);			
		}
		return jPanelRegStart;
	}
	/**
	 * This method initializes jJPanelRegEnd	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelRegEnd() {
		if (jPanelRegEnd == null) {
			jPanelRegEnd = new JPanel();
			jPanelRegEnd.setLayout(new FlowLayout());		
			jLabelRegEnd = new JLabel("End:");
			//jLabelRegEnd.setPreferredSize(new Dimension(40, 22));
			jLabelRegEnd.setHorizontalAlignment(JLabel.RIGHT);
			SpinnerModel sModel = new SpinnerNumberModel(2, 2, 3, 1); //init, min, max, step
			jSpinnerRegEnd = new JSpinner(sModel);
			//jSpinnerRegEnd = new JSpinner();
			jSpinnerRegEnd.setPreferredSize(new Dimension(60, 22));
			jSpinnerRegEnd.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerRegEnd.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			ftf.setEditable(false);
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelRegEnd.add(jLabelRegEnd);
			jPanelRegEnd.add(jSpinnerRegEnd);			
		}
		return jPanelRegEnd;
	}
	//------------------------------------------------------------------------------------	
	/**
	 * This method initializes jCheckBoxShowPlot	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private  JCheckBox getJCheckBoxShowPlot() {
		if (jCheckBoxShowPlot == null) {
			jCheckBoxShowPlot = new JCheckBox();
			jCheckBoxShowPlot.setText("ShowPlot");
			jCheckBoxShowPlot.addActionListener(this);			
			jCheckBoxShowPlot.setActionCommand("parameter");			
		}
		return jCheckBoxShowPlot;
	}
	//------------------------------------------------------------------------------------
	/**
	 * This method initializes jCheckBoxDeleteExistingPlot	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private  JCheckBox getJCheckBoxDeleteExistingPlot() {
		if (jCheckBoxDeleteExistingPlot == null) {
			jCheckBoxDeleteExistingPlot = new JCheckBox();
			jCheckBoxDeleteExistingPlot.setText("DeleteExistingPlot");
			jCheckBoxDeleteExistingPlot.addActionListener(this);			
			jCheckBoxDeleteExistingPlot.setActionCommand("parameter");			
		}
		return jCheckBoxDeleteExistingPlot;
	}

    //----------------------------------------------------------------------------------------------------------
	public void actionPerformed(ActionEvent e) {
		//System.out.println("IqmFracHiguchiGUI: event e: " +e.getActionCommand());
		if ("reset".equals(e.getActionCommand())) {
			ParameterBlockJAI pbJAI = new ParameterBlockJAI("IqmFracHiguchi".toLowerCase());
			IqmTools.setCurrParameterBlockJAI(pbJAI);
			this.setParameterBlock(pbJAI);
			this.setParameterValues();
				
			numMaxK = this.getMaxHiguchiNumber(width,  height);
			//numK = numMaxK;
			numK = numMaxK/3;
			this.setJSpinnerNumKandRegEnd(numK, numMaxK);
		
			this.updateIqmOperatorGUI();  //if necessary here or some lines above
			this.setParameterBlock();
			this.setParameterValues();
			this.pack();
			//this.reset();
					
		}
		if ("parameter".equals(e.getActionCommand())) {		
		
			if (buttProj == e.getSource() || buttSep == e.getSource() || buttCont == e.getSource() || buttMeand == e.getSource() ){			
			}
			this.updateIqmOperatorGUI();  //if necessary here or some lines above
			this.setParameterBlock();
			this.setParameterValues();
		}

		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}

	}
	//-------------------------------------------------------------------------------------------------
	@Override
	public void stateChanged(ChangeEvent e) {
		
		numK         = ((Number)jSpinnerNumK.getValue()).intValue();
		int regStart = ((Number)jSpinnerRegStart.getValue()).intValue();
		int regEnd   = ((Number)jSpinnerRegEnd.getValue()).intValue();
		
		jSpinnerNumK.removeChangeListener(this);
		jSpinnerRegStart.removeChangeListener(this);
		jSpinnerRegEnd.removeChangeListener(this);
		
		if (jSpinnerNumK == e.getSource()) {
			//if(regEnd > numK){
				jSpinnerRegEnd.setValue(numK);
				regEnd = numK; 
			//}
			if(regStart >= regEnd){
				jSpinnerRegStart.setValue(regEnd-1);
				regStart = regEnd-1;
			}
		}
		if (jSpinnerRegEnd == e.getSource()){
			if (regEnd > numK){
				jSpinnerRegEnd.setValue(numK);
				regEnd = numK; 
			}
			if (regEnd <= regStart){
				jSpinnerRegEnd.setValue(regStart+1);
				regEnd = regStart+1; 
			}
		}
		if (jSpinnerRegStart == e.getSource()){
			if (regStart >= regEnd){
				jSpinnerRegStart.setValue(regEnd-1);
				regStart = regEnd-1;				
			}
		}
		
		jSpinnerNumK.addChangeListener(this);
		jSpinnerRegStart.addChangeListener(this);
		jSpinnerRegEnd.addChangeListener(this);

		this.updateIqmOperatorGUI();  //if necessary here or some lines above
		this.setParameterBlock();
		this.setParameterValues();
		
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}
		
	}
	//-------------------------------------------------------------------------------------------------
	public static void main() {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				IqmFracHiguchiGUI gui = new IqmFracHiguchiGUI();
			    gui.createIqmOperatorGUI();

			}
		});
	}
	
}//END
